<?php

namespace qhweb\phpsm\ecc;

use Mdanter\Ecc\Crypto\Signature\Signer;
use Mdanter\Ecc\Curves\NistCurve;
use Mdanter\Ecc\Curves\SecgCurve;
use Mdanter\Ecc\Math\GmpMathInterface;
use Mdanter\Ecc\Math\MathAdapterFactory;
use Mdanter\Ecc\Primitives\CurveFp;
use Mdanter\Ecc\Primitives\CurveFpInterface;
use Mdanter\Ecc\Primitives\CurveParameters;

use qhweb\phpsm\ecc\sm2\Sm2Curve;
/**
 * ECC 工厂类
 * 
 * 提供创建适配器、SM2/NIST/SECG 曲线工厂、签名器以及自定义曲线的入口。
 * 采用类继承方式扩展曲线工厂（亦可通过覆盖曲线工厂实现）。
 * @package     qhweb\phpsm\ecc
 * @author      qhweb
 * @version     1.0.0
 */
class EccFactory {

    /**
     * 为当前运行环境选择并创建最合适的数学适配器
     *
     * @param  bool $debug 是否开启调试模式（输出数学运算跟踪）
     * @return GmpMathInterface 数学适配器实例
     * @throws \RuntimeException 当无法创建适配器时抛出
     */

    public static function getAdapter(bool $debug = false): GmpMathInterface
    {
        $adapter = MathAdapterFactory::getAdapter($debug);
        return $adapter;
    }

    /**
     * 创建 SM2 曲线工厂
     *
     * @param  GmpMathInterface|null $adapter 数学适配器；为 null 时自动调用 getAdapter()
     * @return Sm2Curve SM2 曲线工厂实例
     */
    public static function getSmCurves(GmpMathInterface $adapter = null): Sm2Curve
    {
        $adapter = $adapter ?: self::getAdapter();
        // var_dump($adapter);
        return new Sm2Curve($adapter);
    }
    

    /**
     * 创建 NIST 推荐曲线工厂
     *
     * @param  GmpMathInterface|null $adapter 数学适配器；为 null 时自动调用 getAdapter()
     * @return NistCurve NIST 曲线工厂实例
     */

    public static function getNistCurves(GmpMathInterface $adapter = null): NistCurve
    {
        return new NistCurve($adapter ?: self::getAdapter());
    }

    /**
     * 创建 SECG 推荐曲线工厂
     *
     * @param  GmpMathInterface|null $adapter 数学适配器；为 null 时自动调用 getAdapter()
     * @return SecgCurve SECG 曲线工厂实例
     */
    public static function getSecgCurves(GmpMathInterface $adapter = null): SecgCurve
    {
        return new SecgCurve($adapter ?: self::getAdapter());
    }

    /**
     * 根据给定参数创建自定义椭圆曲线
     *
     * @param  int                  $bitSize 曲线位数（如 256）
     * @param  \GMP                  $prime   有限域素数 p
     * @param  \GMP                  $a       曲线参数 a
     * @param  \GMP                  $b       曲线参数 b
     * @param  GmpMathInterface|null $adapter 数学适配器；为 null 时自动调用 getAdapter()
     * @return CurveFpInterface      曲线实例
     */
    public static function createCurve(int $bitSize, \GMP $prime, \GMP $a, \GMP $b, GmpMathInterface $adapter = null): CurveFpInterface
    {
        return new CurveFp(new CurveParameters($bitSize, $prime, $a, $b), $adapter ?: self::getAdapter());
    }

    /**
     * 创建签名器
     *
     * @param  GmpMathInterface|null $adapter 数学适配器；为 null 时自动调用 getAdapter()
     * @return Signer 签名器实例
     */
    public static function getSigner(GmpMathInterface $adapter = null): Signer
    {
        return new Signer($adapter ?: self::getAdapter());
    }
    
}
